home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / crh_n.arc / NANSI_F.ASM < prev    next >
Assembly Source File  |  1990-03-09  |  19KB  |  730 lines

  1.     page    66, 132
  2. ;----- nansi_f.asm ---------------------------------------------
  3. ; The ANSI control subroutines.
  4. ; (C) 1986 Daniel Kegel, Pasadena, CA
  5. ; May be distributed for educational and personal use only
  6. ; Each routine is called with the following register usage:
  7. ;  AX = max(1, value of first parameter)
  8. ;  Z flag is set if first parameter is zero.
  9. ;  CX = number of paramters
  10. ;  SI = offset of second parameter from CS
  11. ;  DS = CS
  12. ;  ES:DI points to the current location on the memory-mapped screen.
  13. ;  DX is number of characters remaining on the current screen line.
  14.  
  15. ; The control routine is free to trash AX, BX, CX, SI, and DS.
  16. ; It must preserve ES, and can alter DX and DI if it wants to move the
  17. ; cursor.
  18. ;
  19. ; Revisions:
  20. ;  19 Aug 85: Fixed horrible bug in insert/delete line.
  21. ;  26 Aug 85: Fixed simple limit-to-one-too-few-lines bug in ins/del line;
  22. ;  anyway, it inserts 24 lines when on line 2 now.  Whether it's fixed...
  23. ;  4 Sept 85: Fixed bug created on 26 Aug 85; when limiting ins/del line
  24. ;  count, we are clearing, not scrolling; fixed BIOS call to reflect this.
  25. ;  30 Jan 86: Added EGA cursor patch
  26. ;  31 Jan 86: Disabled insert/delete char in graphics modes
  27. ;          Implemented keyboard redefinition reset
  28. ;  1 Feb 86: added video_mode and max_x test after mode set
  29. ; c.r. henderson
  30. ;  3 mar 90: added a response to ESC[c.  Response is now 'nansi' followed
  31. ;            by a carriage return
  32. ;----------------------------------------------------------------
  33.  
  34.     include nansi_d.asm
  35.  
  36.     ; To nansi_p.asm
  37.     public    ansi_fn_table
  38.  
  39.  
  40.     ; From nansi.asm
  41.     extrn    port_6845:word
  42.     extrn    cur_coords:word, saved_coords:word
  43.     extrn    cur_x:byte, max_x:byte
  44.     extrn    cur_y:byte, max_y:byte
  45.     extrn    cur_attrib:byte, wrap_flag:byte
  46.     extrn    xy_to_regs:near
  47.     extrn    get_blank_attrib:near
  48.     extrn    xlate_tab_ptr:word
  49.     extrn    cpr_esc:byte, cprseq:word
  50.     extrn    id_str:byte, id_end:byte, idseq:word
  51.     extrn    video_mode:byte
  52.     extrn    lookup:near
  53.     extrn    in_g_mode:near
  54.  
  55.     ; from nansi_p.asm
  56.     extrn    param_buffer:word    ; used in keyboard programming
  57.     extrn    param_end:word
  58.     extrn    redef_end:word
  59.  
  60. keybuf    struc                ; used in making cpr sequence
  61. len    dw    ?
  62.  
  63. adr    dw    ?
  64. keybuf    ends
  65.  
  66.  
  67. ABS40    segment at 40h
  68.     org    1ah
  69. buffer_head    dw    ?    ; Used in 'flush input buffer' dos call.
  70. buffer_tail    dw    ?
  71.  
  72.     org    49h
  73. crt_mode    db    ?
  74. crt_cols    dw    ?
  75. crt_len        dw    ?
  76. crt_start    dw    ?
  77. cursor_posn    dw    8 dup (?)
  78. cursor_mode    dw    ?
  79. active_page    db    ?
  80. addr_6845    dw    ?
  81. crt_mode_set    db    ?
  82. crt_palette    db    ?
  83.  
  84.  
  85. ABS40    ends
  86.  
  87. code    segment byte public 'CODE'
  88.     assume cs:code, ds:code
  89.  
  90. ;----- byteout ---------------------------------------------------
  91. ; Converts al to a decimal ASCII string (in 0..99),
  92. ; stores it at ES:DI++.  Returns DI pointing at byte after last digit.
  93. ; Destroys DL.
  94.  
  95. byteout proc    near
  96.     aam
  97.     add    ax, 3030h
  98.     xchg    ah, al
  99.     stosb
  100.     xchg    ah, al
  101.     stosb
  102.     ret
  103. byteout endp
  104.  
  105. ;----- ansi_fn_table -----------------------------------
  106.  
  107. ; Table of offsets of terminal control subroutines in order of
  108. ; the character that invokes them, @..Z, a..z.    Exactly 53 entries.
  109. ; All the subroutines are defined below in this module.
  110. ansi_fn_table    label    word
  111.     dw    ic,  cup, cdn, cfw, cbk        ; @, A, B, C, D
  112.     dw    nul, nul, nul, hvp, nul        ; E, F, G, H, I
  113.     dw    eid, eil, il,  d_l, nul        ; J, K, L, M, N
  114.     dw    nul, dc,  nul, nul, nul        ; O, P, Q, R, S
  115.     dw    nul, nul, nul, nul, nul        ; T, U, V, W, X
  116.     dw    nul, nul            ; Y, Z
  117.     dw    nul, nul, id,  nul, nul        ; a, b, c, d, e  CRH 3-9-90
  118.     dw    hvp, nul, sm,  nul, nul        ; f, g, h, i, j
  119.     dw    nul, rm,  sgr, dsr, nul        ; k, l, m, n, o
  120.     dw    key, nul, nul, scp, nul        ; p, q, r, s, t
  121.     dw    rcp, nul, nul, nul, xoc        ; u, v, w, x, y
  122.     dw    nul                ; z
  123.  
  124. ansi_functions    proc    near        ; set return type to NEAR
  125.  
  126. ;----- nul ---------------------------------------------
  127. ; No-action ansi sequence; called when unknown command given.
  128.  
  129. nul:    ret
  130.  
  131. ;----- Cursor Motion -----------------------------------------------
  132.  
  133. ;-- cursor to y,x
  134. hvp:    or    al, al        ; First parameter is desired Y coordinate.
  135.     jz    hvp_yok
  136.     dec    ax        ; Convert to zero-based coordinates.
  137. hvp_yok:mov    cur_y, al
  138.     ; Get second parameter, if it is there, and set X with it.
  139.     xor    ax, ax
  140.     cmp    cx, 2        ; was there a second parameter?
  141.     jb    hvp_xok
  142.     lodsb            ; yes.
  143.     or    al, al
  144.     jz    hvp_xok
  145.     dec    ax        ; convert to zero-based coordinates.
  146. hvp_xok:mov    cur_x, al
  147.  
  148.     ; Clip to maximum coordinates.
  149. hvp_set:
  150.  
  151.     mov    ax, cur_coords        ; al = x, ah = y
  152.     cmp    al, max_x
  153.     jbe    hvp_sxok
  154.         mov    al, max_x
  155.         mov    cur_x, al
  156. hvp_sxok:
  157.     cmp    ah, max_y
  158.     jbe    hvp_syok
  159.         mov    al, max_y
  160.         mov    cur_y, al
  161. hvp_syok:
  162.     ; Set values of DX and DI accordingly.
  163.     call    xy_to_regs
  164.     ret
  165.  
  166. ;-- cursor forward --
  167. cfw:    add    cur_x, al
  168.     jmp    hvp_set
  169.  
  170. ;-- cursor back -----
  171. cbk:    sub    cur_x, al
  172.  
  173.     jae    cbk_ok
  174.         mov    cur_x, 0
  175. cbk_ok: jmp    hvp_set
  176.  
  177. ;-- cursor down -----
  178. cdn:    add    cur_y, al
  179.     jmp    hvp_set
  180.  
  181. ;-- cursor up -------
  182. cup:    sub    cur_y, al
  183.     jae    cup_ok
  184.         mov    cur_y, 0
  185. cup_ok: jmp    hvp_set
  186.  
  187. ;-- save cursor position --------------------------------------
  188. scp:    mov    ax, cur_coords
  189.     mov    saved_coords, ax
  190.     ret
  191.  
  192. ;-- restore cursor position -----------------------------------
  193. rcp:    mov    ax, saved_coords
  194.  
  195.     mov    cur_coords, ax
  196.     jmp    hvp_set        ; Clip in case we have switched video modes.
  197.  
  198. ;-- set graphics rendition ------------------------------------
  199. ; Modifies the color in which new characters are written.
  200.  
  201. sgr:    dec    si        ; get back pointer to first parameter
  202.     or    cx, cx        ; Did he give any parameters?
  203.     jnz    sgr_loop
  204.         mov    byte ptr [si], 0    ; no parameters, so fake
  205.         inc    cx            ; one with the default value.
  206.     ; For each parameter
  207. sgr_loop:
  208.         lodsb                ; al = next parameter
  209.         ; Search color table
  210.         push    cx
  211.         mov    cx, colors
  212.         mov    bx, offset color_table-3
  213. sgr_search:
  214.             add    bx, 3
  215.             cmp    al, byte ptr [bx]
  216.  
  217.             loopnz    sgr_search    ; until match found or done
  218.         jnz    sgr_loopx
  219.  
  220.         ; If parameter named a known color, set the current
  221.         ; color variable.
  222.         mov    ax, [bx+1]
  223.         and    cur_attrib, al
  224.         or    cur_attrib, ah
  225. sgr_loopx:
  226.         pop    cx
  227.         loop    sgr_loop        ; until no more parameters.
  228.     ret
  229.  
  230. ;-- erase in line ----------------------------------------
  231. ; Uses BIOS to scroll away a one-line rectangle
  232. eil:    push    dx
  233.     mov    cx, cur_coords
  234.     mov    dh, ch
  235.     jmp    short scrollem
  236.  
  237. ;-- erase in display -------------------------------------
  238.  
  239. ; Uses BIOS to scroll away all of display
  240. eid:    jz    eid0    ; If param was originally zero, z flag is set...
  241. ;    
  242.     cmp    al, 2    ; Home and then clear to eop
  243.     je    eid2
  244. ;
  245.     cmp    al, 1    ; Clear from top of page?
  246.     jnz    eid_ignore
  247. ;
  248. eid1:    push    dx
  249.     mov    dx, cur_coords; current is lower right of this line
  250.     mov    cx, 0    ;    clear square above left of cur_coords
  251.     or    dl, dl    ;    at first char position on this line?
  252.     jz    eid1a   ;    yes, so ignore this line
  253.     sub    dl, 1    ;    blank chars b4 but not including curs lcn
  254.     call    get_blank_attrib
  255.     mov    bh, ah
  256.     mov    ax, 600h
  257.     int    10h
  258. eid1a:    cmp    dh, 0    ; On top row, if so, simply exit
  259.     jz    eidx
  260. ;
  261. ; Not on top row, must clear all above line to right of cursor psn
  262. ;
  263.     sub    dh, 1
  264.     mov    dl, max_x
  265.     call    get_blank_attrib
  266.     mov    bh, ah
  267.     jmp    eidi    ; Call int 10 to perform scroll
  268. ;
  269. ; '0' param
  270. ;
  271. eid0:    call    eil    ; Yes, clr-eop by first clearing rest of current line
  272.     mov    cx, cur_coords
  273.     cmp    ch, max_y
  274.     jz    eid_ignore    ; Just exit if last line now.
  275. ;
  276.     push    dx    ; then clearing to end of page
  277.     mov    cl, 0    ;    upper left column
  278.     add    ch, 1    ;  at next row from current
  279.     mov    dh, max_y; to bottom right row
  280.     jmp    scrollem;   then rest of page
  281. eid2:    if    cls_homes_too
  282.         mov    cur_coords, 0
  283.         call    xy_to_regs
  284.     endif
  285.     push    dx
  286.     xor    cx, cx
  287.     mov    dh, max_y
  288. scrollem:
  289.     call    get_blank_attrib
  290.     mov    bh, ah
  291.     mov    dl, max_x
  292. eidi:    mov    ax, 600h
  293.     int    10h
  294. eidx:    pop    dx
  295. eid_ignore:
  296.     ret
  297.  
  298. ;-- device status report --------------------------------
  299.  
  300. ; Stuffs an escape, a left bracket, current Y, semicolon, current X,
  301. ; a capital R, and a carriage return into input stream.
  302. ; The coordinates are 1 to 3 decimal digits each.
  303.  
  304. dsr:    push    di
  305.     push    dx
  306.     push    es
  307.     mov    ax, cs
  308.     mov    es, ax
  309.     std            ; Store string in reversed order for fun
  310.     mov    di, offset cpr_esc - 2
  311.     mov    al, cur_y
  312.     inc    al        ; convert to one-based coords
  313.     call    byteout        ; row
  314.     mov    al, ';'        ; ;
  315.     stosb
  316.     mov    al, cur_x
  317.     inc    al        ; convert to one-based coords
  318.     call    byteout        ; column
  319.     mov    al, 'R'        ; R ANSI function 'Cursor Position Report'
  320.     stosb
  321.  
  322.     mov    al, 13
  323.     mov    word ptr cprseq.adr, di ; save pointer to last char in string
  324.     stosb                ; send a carriage return, too
  325.     mov    ax, offset cpr_esc
  326.     sub    ax, di            ; ax is # of characters in string
  327.     mov    word ptr cprseq.len, ax ; pass info to the getchar routine
  328.     cld
  329.     pop    es
  330.     pop    dx
  331.     pop    di
  332.     ret
  333.  
  334. ;-- keyboard reassignment -------------------------------
  335. ; Key reassignment buffer is between param_end and redef_end+2, exclusive.
  336. ; When it shrinks or grows, param_end is moved.
  337. ; Format of an entry is as follows:
  338. ;   highest address -> length:word (may be 0)
  339. ;               key to replace:word     (either hi or low byte is zero)
  340. ;               .
  341. ;               .    new key value, "length" bytes long
  342. ;               .
  343.  
  344. ;   lowest address  -> next entry, or free space.
  345. ; If no arguments are given, keyboard is reset to default condition.
  346. ; Otherwise, first parameter (or first two, if first is zero) defines
  347. ; the key whose value is to be changed, and the following parameters
  348. ; define the key's new, possibly zero-length, value.
  349.  
  350. key:
  351.     ; Is this a reset?
  352.     or    cx, cx
  353.     jz    key_init
  354.     ; Get the first (or first two) parameters
  355.     cld
  356.     dec    si    ; point to first param
  357.     dec    cx    ; Assume it's a fn key, get two params
  358.     dec    cx
  359.     lodsw
  360.     or    al, al    ; Is it a function key?
  361.     jz    key_fnkey
  362.         ; It's not a function key- put second param back
  363.         inc    cx
  364.         dec    si
  365.  
  366. key_fnkey:
  367.     ; Key to redefine now in AX.  If it's already redefined,
  368.     ; lookup will set Z, point SI to redef string, set CX to its length.
  369.     push    di
  370.     push    es
  371.     push    cx
  372.     push    si
  373.  
  374.     std            ; moving up, must move from top down
  375.     push    ds
  376.     pop    es        ; string move must have ES=DS
  377.     call    lookup        ; rets Z if redefined...
  378.     jnz    key_newkey
  379.     ; It's already defined.  Erase its old definition- i.e., move
  380.     ; region param_end+1..SI-1 upwards CX+4 bytes, add CX+4 to param_end.
  381.     add    cx, 4
  382.     mov    bp, param_end    ; save old value in bp...
  383.     add    param_end, cx
  384.     dec    si        ; start at (SI-1)
  385.     mov    di, si
  386.     add    di, cx        ; move to (start + CX+4)
  387.  
  388.     mov    cx, si
  389.     sub    cx, bp        ; length of region old_param_end+1..start
  390.     rep    movsb
  391. key_newkey:
  392.     ; Key not redefined.  See if there's enough room to redefine it.
  393.     pop    si        ; get back pointer to redef string
  394.     pop    cx        ; get back number of bytes in redef string
  395.     mov    di, param_end    ; hi byte of new redef record, hi byte of len
  396.     sub    di, 4        ; hi byte of new data field
  397.     mov    bx, di
  398.     sub    bx, cx        ; hi byte of remaining buffer space
  399.     sub    bx, 16        ; better be at least 16 bytes room
  400.     cmp    bx, param_buffer
  401.     jb    key_popem    ; nope- forget it.
  402.     ; Nothing in the way now!
  403.     mov    [di+3], cx    ; save length field
  404.     mov    [di+1], ax    ; save name field
  405.     jcxz    key_nullstring
  406. key_saveloop:            ; save data field
  407.     movsb
  408.     add    si, 2        ; input string ascending, output descending
  409.  
  410.     loop    key_saveloop
  411. key_nullstring:
  412.     mov    param_end, di    ; save adr of new hi byte of free area
  413. key_popem:
  414.     pop    es
  415.     pop    di
  416.  
  417. key_exit:
  418.     cld
  419.     ret
  420.  
  421. key_init:
  422.     ; Build the default redefinition table:
  423.     ;    control-printscreen -> control-P
  424.     push    es
  425.     push    ds
  426.     pop    es
  427.     std
  428.     mov    di, redef_end
  429.     mov    ax, 1
  430.     stosw
  431.  
  432.     mov    ax, 7200h    ; control-printscreen
  433.     stosw
  434.     mov    al, 16        ; control P
  435.     stosb
  436.     mov    param_end, di    ; save new bottom of redef table
  437.     pop    es
  438.     jmp    key_exit
  439.  
  440. ;---- Delete/Insert Lines -------------------------------
  441. ; AL is number of lines to delete/insert.
  442. ; Preserves DX, DI; does not move cursor.
  443.  
  444. d_l:    ; Delete lines.
  445.     mov    ah, 6            ; BIOS: scroll up
  446.     jmp    short il_open
  447.  
  448. il:    ; Insert lines.
  449.     mov    ah, 7            ; BIOS: scroll down
  450.  
  451. il_open:
  452.     ; Whether inserting or deleting, limit him to (max_y - cur_y) lines;
  453.  
  454.     ; if above that, we're just clearing; set AL=0 so BIOS doesn't burp.
  455.     mov    bh, max_y
  456.     sub    bh, cur_y
  457.     cmp    al, bh
  458.     jbe    il_ok            ; DRK 9/4...
  459.         mov    al, 0        ; he tried to move too far
  460. il_ok:
  461.     push    ax
  462.     call    get_blank_attrib
  463.     mov    bh, ah            ; color to use on new blank areas
  464.     pop    ax            ; AL is number of lines to scroll.
  465.  
  466.     mov    cl, 0            ; upper-left-x of data to scroll
  467.     mov    ch, cur_y        ; upper-left-y of data to scroll
  468.     push    dx
  469.     mov    dl, max_x        ; lower-rite-x
  470.     mov    dh, max_y        ; lower-rite-y (zero based)
  471.     int    10h            ; call BIOS to scroll a rectangle.
  472.     pop    dx
  473.     ret                ; done.
  474.  
  475.  
  476. ;-- Insert / Delete Characters ----------------------------
  477. ; AL is number of characters to insert or delete.
  478. ; Preserves DX, DI; does not move cursor.
  479.  
  480. ic:    mov    ch, 1            ; 1 => swap dest & source below
  481.     jmp    short dc_ch
  482.  
  483. dc:    mov    ch, 0
  484.  
  485. dc_ch:
  486.     call    in_g_mode
  487.     jnc    dc_ret            ; | if in graphics mode, ignore.
  488.  
  489.     ; AL = number of chars to ins or del (guarenteed nonzero).
  490.     ; Limit him to # of chars left on line.
  491.     cmp    al, dl
  492.     jbe    dc_cok
  493.         mov    al, dl
  494. dc_cok:
  495.     push    di            ; DI is current address of cursor
  496.     xchg    ax, cx            ; CX gets # of chars to ins/del
  497.  
  498.     mov    bp, cx            ; BP gets # of columns to clear.
  499.  
  500.     ; Set up source = destination + cx*2, count = dx - cx
  501.     mov    ch, 0            ; make it a word
  502.     mov    si, di
  503.     add    si, cx
  504.     add    si, cx
  505.     neg    cl
  506.     add    cl, dl
  507.     mov    ch, 0            ; CX = # of words to transfer
  508.     cld                ; REP increments si & di
  509.  
  510.     ; If this is an insert, then flip transfer around in both ways.
  511.     test    ah, 1
  512.     jz    dc_noswap
  513.         xchg    di, si        ; source <-> dest
  514.         std            ; up <-> down
  515.         mov    ax, cx        ; make move over same range
  516.         dec    ax
  517.         add    ax, ax        ; AX=dist from 1st to last byte.
  518.         add    di, ax        ; Start transfer at high end of block
  519.  
  520.         add    si, ax        ;  instead of low end.
  521. dc_noswap:
  522.     ; Move those characters.
  523.     push    es
  524.     pop    ds
  525.     rep    movsw
  526.     mov    cx, bp
  527.     ; Figure out what color to make the new blanks.
  528.     call    get_blank_attrib
  529.     mov    al, ' '
  530.     ; Blank out vacated region.
  531.     rep    stosw
  532.  
  533.     ; All done.
  534.     cld                ; restore normal REP state and
  535.     pop    di            ;  cursor address.
  536. dc_ret: ret
  537.  
  538. ;---- identify terminal as nansi --------------- added by:  CRH on 3-9-90
  539. id:    push    di
  540.     push    dx
  541.     push    es
  542.     mov    ax, cs
  543.     mov    es, ax
  544.     mov    di, offset id_str
  545.     mov    ax, offset id_end
  546.     sub    ax, di
  547.     inc    ax
  548.     mov    word ptr idseq.len, ax ; # chars in string 'nansi-cr-'
  549.     mov    word ptr idseq.adr, di ; pass address of string to getchar
  550.  
  551. ;
  552. ; return, our work's done
  553. ;
  554.     pop    es
  555.     pop    dx
  556.     pop    di
  557.     ret
  558.  
  559. ;---- set / reset mode ---------------------------------------
  560. ; Sets graphics/text mode; also sets/resets "no wrap at eol" mode.
  561.  
  562. sm:    mov    cl, 0ffh    ; set
  563. sm_rs:
  564.     ; Is it "wrap at eol" ?
  565.     cmp    al, 7
  566.     jnz    sm_notwrap
  567.         mov    wrap_flag, cl    ; true = wrap at EOL
  568.         jmp    short sm_done
  569. sm_notwrap:
  570.     ; Is it "set highest number of screen lines available"?
  571.     cmp    al, 43
  572.     jnz    sm_video
  573.         ; Only valid for the Enhanced Graphics Adaptor on
  574.         ; a monochrome display or an enhanced color display.
  575.         ; Test presence of EGA by calling BIOS fn 12h.10h.
  576.         mov    ah, 12h
  577.         mov    bx, 0ff10h
  578.         int    10h            ; bh=0-1, bl=0-3 if EGA
  579.         test    bx, 0FEFCH
  580.         jnz    sm_done            ; sorry, charlie
  581. ;        mov    port_6845, 3d4h
  582. ;        mov    al, video_mode
  583.  
  584. ;        and    al, 7
  585. ;        cmp    al, 7            ; monochrome monitor?
  586. ;        jnz    sm_colormon
  587. ;            mov    byte ptr port_6845, low(3b4h)
  588. ;sm_colormon:
  589.         ; 43 line mode only allowed in text modes, for now.
  590.         call    in_g_mode
  591.         jnc    sm_done
  592.  
  593.         mov    ah, 0            ; "Set video mode"
  594.         mov    al, video_mode        ; Re-init current mode
  595.         int    10h
  596.  
  597.         mov    ax,1112h        ; Load 8x8 font
  598.         mov    bl,0            ; (instead of 8x14)
  599.         int    10h
  600.  
  601.         mov    ax, 1200h        ; Load new printscreen
  602.         mov    bl, 20h
  603.         int    10h
  604.  
  605.  
  606.         mov    ah,1
  607.         mov    cx,0707h        ; (Load cursor scan lines)
  608.         int    10h
  609.         ; | Patch; this gotten by painful observation of
  610.         ; | IBM's professional editor.    I think there's a
  611.         ; | documented bug in Video Bios's "load cursor scan line"
  612.         ; | call; try looking in latter 1985 PC Tech Journal.
  613.         mov    dx, port_6845        ; '6845' command reg
  614.         mov    al, 10
  615.         out    dx, al
  616.         jmp    $+2
  617.         inc    dx
  618.         mov    al, 7
  619.         out    dx, al            ; set cursor start line
  620.         ; Assume that gets us 43 lines.
  621.         mov    max_y, 42
  622.         jmp    short sm_home
  623. sm_video:
  624.     ; It must be a video mode.  Call BIOS.
  625.     mov    ah, 0        ; "set video mode"
  626.     int    10h
  627.  
  628.     ; Assume that gets us 25 lines.
  629.     mov    max_y, 24
  630. sm_home:
  631.     ; Read the BIOS buffer address/cursor position variables.
  632.     mov    ax, abs40
  633.     push    ds
  634.     mov    ds, ax
  635.     assume    ds:abs40
  636.     ; Find current video mode and screen size.
  637.     mov    ax,word ptr crt_mode    ; al = crt mode; ah = # of columns
  638.     pop    ds
  639.     mov    video_mode, al
  640.     dec    ah            ; ah = max column
  641.     mov    max_x, ah
  642.  
  643.     ; Since cursor may end up in illegal position, it's best to
  644.     ; just go home after switching video modes.
  645.     mov    cur_coords, 0
  646.     call    xy_to_regs
  647. sm_done:
  648.     ret
  649.  
  650.  
  651. rm:    mov    cl, 0        ; reset
  652.     jmp    sm_rs
  653.  
  654. ;------- Output Character Translation ----------------------
  655. ; A decidedly nonstandard function, possibly useful for editing files
  656. ; intended to be printed by daisywheel printers with strange wheels.
  657. ; (The letter 'y' was chosen to conflict with the VT100 self-test command.)
  658. ; Usage: ESC [ #1;#2 y
  659. ; where #1 is the character to redefine
  660. ;    #2 is the new display value
  661. ; If only ESC [ #1 y is sent, character #1 is reset to its default value.
  662. ; If only ESC [ y is sent, the entire table is reset to the default value.
  663. ; (If only ESC [ #1; y is sent, character #1 is set to zero... sigh.)
  664.  
  665. xoc:    ; Xlate output character
  666.     mov    bx, xlate_tab_ptr
  667.     jcxz    xoc_reset    ; if no parameters, reset table to 1:1
  668.     dec    si        ; point to first parameter
  669.     lodsw            ; first parameter to AL, second to AH
  670.     dec    cx        ; is parameter count 1?
  671.  
  672.     jnz    xoc_bothparams
  673.         mov    ah, al    ; if only one param, reset that char.
  674. xoc_bothparams:
  675.     add    bl, al
  676.     adc    bh, 0        ; bx points to entry for char AL
  677.     mov    byte ptr [bx], ah    ; change that entry
  678. xoc_done:
  679.     ret
  680.  
  681. xoc_reset:
  682.     ; Fill table with default values- i.e. 0, 1, 2, ... 255.
  683.     xor    ax, ax
  684. xoc_loop:
  685.     mov    byte ptr [bx], al
  686.     inc    bx
  687.     inc    al
  688.     jnz    xoc_loop
  689.     jmp    xoc_done
  690.  
  691. ansi_functions    endp    ; end dummy procedure block
  692.  
  693.  
  694.  
  695.  
  696. ;-------- Color table -----------------------------------------
  697. ; Used in "set graphics rendition"
  698. colors    equ    22            ; number of colors in table
  699. color_table:
  700.     db    0, 000h,07h        ; all attribs off; normal.
  701.     db    1, 0ffh,08h        ; bold
  702.     db    4, 0f8h,01h        ; underline
  703.     db    5, 0ffh,80h        ; blink
  704.     db    7, 0f8h,70h        ; reverse
  705.     db    8, 088h,00h        ; invisible
  706.  
  707.     db    30,0f8h,00h        ; black foreground
  708.     db    31,0f8h,04h        ; red
  709.     db    32,0f8h,02h        ; green
  710.     db    33,0f8h,06h        ; yellow
  711.     db    34,0f8h,01h        ; blue
  712.     db    35,0f8h,05h        ; magenta
  713.     db    36,0f8h,03h        ; cyan
  714.     db    37,0f8h,07h        ; white
  715.  
  716.  
  717.     db    40,08fh,00h        ; black background
  718.     db    41,08fh,40h        ; red
  719.     db    42,08fh,20h        ; green
  720.     db    43,08fh,60h        ; yellow
  721.     db    44,08fh,10h        ; blue
  722.     db    45,08fh,50h        ; magenta
  723.     db    46,08fh,30h        ; cyan
  724.     db    47,08fh,70h        ; white
  725.  
  726.  
  727. code    ends
  728.     end                ; of nansi_f.asm
  729.  
  730.